package com.fastadmin.config.security.simple;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.json.JSONUtil;
import com.fastadmin.common.FAConst;
import com.fastadmin.mapper.impl.ResourceMapper;
import com.fastadmin.mapper.impl.RoleResourceMapper;
import com.fastadmin.pojo.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

import static com.fastadmin.common.FAConst.LoginConst.LOGIN_URL;

/** 配置路径访问限制,若你的用户角色比较简单,不需要存数据库,
 * 可以在ApplicationConfigurerAdapter里配置如
 *    httpSecurity
 *    .authorizeRequests()
 *    .antMatchers("/order").....
 *
 * @author YangKun
 * @date 2019/4/10 10:33.
 */
@Component("accessDecisionService")
public class AccessDecisionService {
    private static final Logger logger = LoggerFactory.getLogger(AccessDecisionService.class);
    @Autowired
    ResourceMapper resourceMapper;

    @Autowired
    RoleResourceMapper roleResourceMapper;

    private AntPathMatcher antPathMatcher = new AntPathMatcher();
    public boolean hasPermission(HttpServletRequest request, Authentication auth) {
        String requestURI = request.getRequestURI();
        Map<String, String> paramMap = ServletUtil.getParamMap(request);
        logger.debug("url->{}", requestURI);
        logger.debug("参数{}", JSONUtil.toJsonPrettyStr(paramMap));
        //未登录
        if (auth instanceof AnonymousAuthenticationToken) {
            return false;
        }
        UserDetails user = (UserDetails) auth.getPrincipal();
        //根据 角色去查询，拥有那些资源
        List<String> urls = queryUrlByAuthorities(user.getAuthorities());
        return urls.stream().anyMatch(requestURI::equals);
    }

    /**
     * 模拟数据库查询用户权限
     * @param authorities 权限，例如 admin ，member
     * @return
     */
    public List<String> queryUrlByAuthorities(Collection<? extends GrantedAuthority> authorities) {
        String roles = CollUtil.join(authorities, ",");
        List<Map<String, Object>> list = roleResourceMapper.findUrlByRolesKey(roles);
        //logger.debug("查询出来的具有权限的url->{}", list);
        return list.stream().collect(ArrayList::new, (l, v) -> l.add(v.get("url").toString()), List::addAll);
    }


}
